﻿/*CLR Version: 4.0.30319.18408
 * Creat Date: 2015/6/5 14:50:19
 * Creat Year: 2015
 * Creator: 程炜.Snail
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;
using System.Data;

namespace Utility.Extensions
{
    /// <summary>
    /// 泛型扩展方法
    /// </summary>
    public static class TExtensions
    {
        /// <summary>
        /// 将source的属性赋值到target中,
        /// 根据target栏位进行判断哪些需要赋值,
        /// 如果source栏位值为Nullable类型则忽略赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="copyFixed">
        /// 是否Copy固定栏位
        /// true: 复制, false: 不复制.[固定栏位: CREATEBY,CREATEON,MODIFYBY,MODIFYON ]
        /// </param>
        /// <returns>返回target</returns>
        public static void CopyTo<T>(this T source, T target, bool copyFixed = false)
        {
            PropertyInfo[] targetProperties = target.GetType().GetProperties();
            foreach (var property in targetProperties)
            {
                var sourceProperty = source.GetType().GetProperty(property.Name);
                if (null != sourceProperty && sourceProperty.CanWrite)
                {
                    var sourceValue = sourceProperty.GetValue(source, null);
                    var propertyTypeName = sourceProperty.PropertyType.Name;
                    if (propertyTypeName.Equals(typeof(string).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<int>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(int).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(bool).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<bool>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(DateTime).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<DateTime>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(float).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<float>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(double).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<double>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(double).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<double>).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(decimal).Name, StringComparison.OrdinalIgnoreCase)
                        || propertyTypeName.Equals(typeof(Nullable<decimal>).Name, StringComparison.OrdinalIgnoreCase))
                    {
                        if (copyFixed || ((!sourceProperty.Name.Equals("CREATEBY", StringComparison.OrdinalIgnoreCase) || (sourceProperty.Name.Equals("CreateBy") && sourceValue != null))
                            && (!sourceProperty.Name.Equals("CREATEON", StringComparison.OrdinalIgnoreCase) || (sourceProperty.Name.Equals("CreateOn") && sourceValue != null))
                            && (!sourceProperty.Name.Equals("MODIFYBY", StringComparison.OrdinalIgnoreCase) || (sourceProperty.Name.Equals("CreateOn") && sourceValue != null))
                            && (!sourceProperty.Name.Equals("MODIFYON", StringComparison.OrdinalIgnoreCase) || (sourceProperty.Name.Equals("CreateOn") && sourceValue != null))
                            ))
                        {
                            target.GetType().InvokeMember(property.Name, BindingFlags.SetProperty, null, target, new object[] { sourceValue });
                        }
                    }
                }
            }
            foreach (var field in target.GetType().GetFields())
            {
                var sField = source.GetType().GetField(field.Name);
                if (null != sField)
                {
                    var fieldValue = sField.GetValue(source);
                    if (fieldValue != null)
                    {
                        target.GetType().InvokeMember(field.Name, BindingFlags.SetField, null, target, new object[] { fieldValue });
                    }
                }
            }
        }
        /// <summary>
        /// 根据 T 类型创建对应的 DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static DataTable CreateDataTable<T>(this T source)
        {
            return DBUtility.DataSet2Object.CreateDataTable<T>();
        }
        /// <summary>
        /// 从List数据转换成DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this IList<T> list)
        {
            return DBUtility.DataSet2Object.ToDataTable(list);
        }
    }
}